package app.spring;

import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;

import app.models.Usuario;
import app.models.enums.StatusUsuario;
import app.repositories.impl.UsuarioRepositoryImpl;
import app.util.Constants;
import app.util.Credentials;
import app.util.Internationalization;

public class CustomAuthenticationProvider implements AuthenticationProvider {
	
	private EntityManager getEntityManager() {
		EntityManagerFactory emf = Persistence.createEntityManagerFactory("default");
		EntityManager ecm = emf.createEntityManager();
		return ecm;
	}
	
	private ResourceBundle bundle = Internationalization.defaultBundle();
	
	public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {
	
		EntityManager em = this.getEntityManager();
		UsuarioRepositoryImpl repository = new UsuarioRepositoryImpl(em);
		String name = authentication.getName();
		String password = authentication.getCredentials().toString();
		Usuario user = repository.autentication(name, password);
		
		if(user == null){
			throw new BadCredentialsException(bundle.getString("usuario.notFound"));
		}
		
		if(user.getStatus().equals(StatusUsuario.INATIVO)){
			throw new BadCredentialsException(bundle.getString("usuario.inactive"));
		}
		
		Credentials.username = name;
		Credentials.password = password;
		Credentials.idUsuario = user.getId().intValue();
		
		GrantedAuthority authority = new GrantedAuthorityImpl(Constants.ROLE_PREFIX + user.getPerfil().getNome().toString());
		
		List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		
		authorities.add(authority);
		
		return new UsernamePasswordAuthenticationToken(user, password, authorities);
	}

	@Override
	public boolean supports(Class<?> authentication) {
		 return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
	}
	
}